package com.bowen.spike.service.impl;

import com.bowen.spike.constants.SystemConstants;
import com.bowen.spike.entity.Voucher;
import com.bowen.spike.mapper.VoucherMapper;
import com.bowen.spike.my_enum.VoucherStatus;
import com.bowen.spike.service.IVoucherService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.ZoneId;

import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 优惠券表 服务实现类
 * </p>
 *
 * @author bowen
 * @since 2025-04-28
 */
@Service
@RequiredArgsConstructor
public class VoucherServiceImpl extends ServiceImpl<VoucherMapper, Voucher> implements IVoucherService {

    private final RedisTemplate<String, String> redisTemplate;
    private final RedissonClient redissonClient;

    @Override
    public void createVoucher(Voucher voucher) throws InterruptedException {
        // 锁全局id
        RLock lock = redissonClient.getLock("voucher:create:" + voucher.getId());
        try {
            if (lock.tryLock()) {
                voucher.setQuantity(voucher.getInventory());
                save(voucher);

                // 设置库存到 Redis
                redisTemplate.opsForValue()
                        .set(SystemConstants.VOUCHER_INVENTORY + voucher.getId(), voucher.getQuantity().toString());
                // 设置状态到 Redis
                redisTemplate.opsForValue()
                        .set(SystemConstants.VOUCHER_STATUS + voucher.getId(), String.valueOf(voucher.getStatus().getValue()));

                // 获取当前时间或指定时间的 Unix 时间戳（单位为秒）
                long expirationTimestamp = voucher.getExpirationTime()
                        .atZone(ZoneId.systemDefault())
                        .toEpochSecond();
                // 设置过期时间到 Redis
                redisTemplate.opsForValue()
                        .set(SystemConstants.VOUCHER_EXPIRATION_TIME + voucher.getId(), String.valueOf(expirationTimestamp));

            }else throw new RuntimeException("添加失败，请稍后重试");
        } finally {
            lock.unlock();
        }
    }

    /**
     * 更新缓存状态和数据库状态
     *
     * @param id
     * @param status
     */
    @Override
    public void updateVoucherStatus(Long id, Integer status) {

        // 枚举手动转换
        VoucherStatus voucherStatus = VoucherStatus.of(status);
        // 更新redis
        redisTemplate
                .opsForValue()
                .set(SystemConstants.VOUCHER_STATUS + id, status.toString());
        //更新数据库
        lambdaUpdate()
                .eq(Voucher::getId, id)
                .set(Voucher::getStatus, voucherStatus)
                .update();
    }
}
